package com.yuke.cloud.service.wmc.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.service.api.omc.dto.OdsGoodSalesApiDto;
import com.yuke.cloud.service.api.omc.service.OmcOrderFeignApi;
import com.yuke.cloud.service.api.pmc.dto.ProdCategoryDto;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecApiDto;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecInfoDto;
import com.yuke.cloud.service.api.pmc.service.PmcFeignApi;
import com.yuke.cloud.service.wmc.dao.WmsStockInMapper;
import com.yuke.cloud.service.wmc.dto.WmsGoodsSalesDto;
import com.yuke.cloud.service.wmc.dto.WmsPurchaseOrderDto;
import com.yuke.cloud.service.wmc.dto.WmsStockInDto;
import com.yuke.cloud.service.wmc.entity.WmsStockIn;
import com.yuke.cloud.service.wmc.entity.WmsStorage;
import com.yuke.cloud.service.wmc.service.WmsStockInService;
import com.yuke.cloud.service.wmc.service.WmsStorageService;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;


/**
 * Created by zys on 2018/12/06.
 */
@Service
@Transactional
public class WmsStockInServiceImpl extends BaseService<WmsStockIn> implements WmsStockInService {
    @Resource
    private WmsStockInMapper wmsStockInMapper;
    @Resource
    private WmsStorageService wmsStorageService;
    @Resource
    private PmcFeignApi pmcFeignApi;
    @Resource
    private OmcOrderFeignApi omcOrderFeignApi;

    @Override
    public List<WmsStockInDto> getWmsStockInByCondition(WmsStockInDto wmsStockInDto) {
        List<WmsStockInDto> wmsStockInDtos = wmsStockInMapper.getWmsStockInByCondition(wmsStockInDto);

        if (wmsStockInDtos == null || wmsStockInDtos.size() < 1) {
            return wmsStockInDtos;
        }

        return wmsStockInDtos;
    }

    /** 需要更新三张表
     *  wms_stock_in 入库表、wms_storage库存商品表、wms_storage_recorder库存记录表
     * @param wmsPurchaseOrderDto
     * @return
     */
    @Override
    @Async
    public CompletableFuture<Integer> insertWmsDto(WmsPurchaseOrderDto wmsPurchaseOrderDto) {
        //操作wms_stock_in 添加商品
        List<WmsStockIn> list = wmsPurchaseOrderDto.getGoodsList();
        Integer i=0;

        //如果是退货入库，先判断商家是否允许退货，如果不允许在推出去
        if (list == null || list.size() < 1) {
            return CompletableFuture.completedFuture(0);
        }

        for (WmsStockIn wmsStockIn : list) {
            if (wmsStockIn.getInNumber() < 1) {
                continue;
            }
            wmsStockIn.setPurchaseId(wmsPurchaseOrderDto.getPurchaseId());
            wmsStockIn.setWarehouseId(wmsPurchaseOrderDto.getWarehouseId());
            wmsStockIn.setInType((byte) 0);
            if (wmsPurchaseOrderDto.getType().equals(2)) {
                wmsStockIn.setInType((byte) 3);
            }
            if (wmsPurchaseOrderDto.getIsDeleted().equals(1)) {
                wmsStockIn.setIsDelete(true);
            }else{
                wmsStockIn.setIsDelete(false);
            }

            wmsStockIn.setUpdateId(wmsPurchaseOrderDto.getUpdateId());
            wmsStockIn.setUpdateTime(new Date());
            i = wmsStockInMapper.insert(wmsStockIn);


        }
        return CompletableFuture.completedFuture(i);
    }

    @Override
    @Async
    public CompletableFuture<Integer> updateWmsStorage(WmsPurchaseOrderDto wmsPurchaseOrderDto) {
        List<WmsStockIn> list = wmsPurchaseOrderDto.getGoodsList();
        Integer i=0;

        //如果是退货入库，先判断商家是否允许退货，如果不允许在推出去
        if (list == null || list.size() < 1) {
            return CompletableFuture.completedFuture(0);
        }

        for (WmsStockIn wmsStockIn : list) {
            if (wmsStockIn.getInNumber() < 1) {
                continue;
            }
            WmsStorage wmsStorage = new WmsStorage();
            wmsStorage.setSpecId(wmsStockIn.getSpecId());
            wmsStorage.setWarehouseId(wmsPurchaseOrderDto.getWarehouseId());

            List<WmsStorage> select = wmsStorageService.select(wmsStorage);

            if (select.size() < 1) {
                if (wmsStockIn.getSupplyPrice() > 0) {
                    wmsStorage.setPurchasePrice(wmsStockIn.getSupplyPrice());
                }
                ProdSpecInfoDto prodSpecInfoDto = pmcFeignApi.getSpecInfoDtoBySpecId(wmsStockIn.getSpecId());
                BeanUtils.copyProperties(prodSpecInfoDto, wmsStorage);
                wmsStorage.setProductId(wmsStockIn.getProductId());
                wmsStorage.setNumber(wmsStockIn.getInNumber());
                wmsStorage.setStockinDate(wmsStockIn.getInboundTime());
                wmsStorage.setMfgDate(wmsStockIn.getMfgDate());
                wmsStorage.setQuality(wmsStockIn.getQuality());

                wmsStorage.setUpdateId(wmsPurchaseOrderDto.getUpdateId());
                wmsStorage.setUpdateTime(new Date());

                wmsStorageService.save(wmsStorage);
            } else if (select.size() > 0) {
                WmsStorage wmsStorage1 = select.get(0);

                if (wmsStockIn.getSupplyPrice() > 0) {
                    wmsStorage.setPurchasePrice(wmsStockIn.getSupplyPrice());
                }
                Integer number = wmsStorage1.getNumber();
                wmsStorage1.setNumber(number + wmsStockIn.getInNumber());
                //todo 进货写入生产日期
                if ((select.get(0).getRemainder() < 1) || ((select.get(0).getNumber() - select.get(0).getLockNumber()) < 1)) {
                    wmsStorage1.setMfgDate(wmsStockIn.getMfgDate());//生产日期
                    int remainder = select.get(0).getNumber() - select.get(0).getLockNumber();
                    if (remainder<0){
                        remainder=0;
                    }
                    wmsStorage1.setRemainder(remainder);//旧货数
                    wmsStorage1.setStockinDate(wmsStockIn.getInboundTime());//入库日期
                }
                wmsStorage1.setUpdateId(wmsPurchaseOrderDto.getUpdateId());
                wmsStorage1.setUpdateTime(new Date());
                wmsStorageService.update(wmsStorage1);
            } else {
                return CompletableFuture.completedFuture(0);
            }
        }
        return CompletableFuture.completedFuture(i);
    }
    @Override
    public List<WmsStockInDto> findGoodsListByPurchase(WmsStockInDto wmsStockInDto) {
        List<WmsStockInDto> list = wmsStockInMapper.getWmsStockInByCondition(wmsStockInDto);
        return list;
    }


    @Override
    public List<WmsGoodsSalesDto> findGoodsSales(WmsGoodsSalesDto goodSalesApiDto) {
        //近三十天的成本单价
        Integer num = 30;
        Calendar ca = Calendar.getInstance();
        // num为天数，可以改变的
        ca.add(Calendar.DATE, -num);
        Date beginTime = ca.getTime();
        System.out.println(beginTime);
        List<WmsGoodsSalesDto> goodSalesApiDtos = wmsStockInMapper.costUnitPrice(goodSalesApiDto, beginTime, null);
        List<Long> list = new ArrayList<>();
        if (goodSalesApiDtos==null||goodSalesApiDtos.size()==0) {
            return null;
        }
            for (WmsGoodsSalesDto salesApiDto : goodSalesApiDtos) {
                if (salesApiDto.getNumberTotal().equals(0) && salesApiDto.getPriceTotal().equals(0)) {
                    list.add(salesApiDto.getSpecId());
                }
            }

        if (list!=null&&list.size()>0){
            List<WmsGoodsSalesDto> limitResult = costUnitPriceBylimit(list);
            for (WmsGoodsSalesDto salesApiDto : goodSalesApiDtos) {
                for (WmsGoodsSalesDto dto : limitResult) {
                    if (salesApiDto.getSpecId().equals(dto.getSpecId())){
                        salesApiDto.setNumberTotal(dto.getNumberTotal());
                        salesApiDto.setPriceTotal(dto.getPriceTotal());
                    }
                }
            }
        }


        return goodSalesApiDtos;
    }



    @Override
    public PageInfo<WmsGoodsSalesDto> goodsSales(Integer page, Integer size, WmsGoodsSalesDto goodsSalesDto) {

        //分类
        if (goodsSalesDto.getParentId() != null || goodsSalesDto.getCategoryId() != null) {
            ProdCategoryDto prodCategoryDto = new ProdCategoryDto();
            prodCategoryDto.setParentId(goodsSalesDto.getParentId());
            prodCategoryDto.setCategoryId(goodsSalesDto.getCategoryId());
            List<Long> leaf = pmcFeignApi.findLeaf(prodCategoryDto);
            goodsSalesDto.setCategoryIdList(leaf);
            goodsSalesDto.setCategoryId(null);
        }

        PageHelper.startPage(page, size);

        //成本均价,当前售价
        List<WmsGoodsSalesDto> salesList = findGoodsSales(goodsSalesDto);

        PageInfo<WmsGoodsSalesDto> result = new PageInfo<>(salesList);

        List<Long> specList = salesList.stream().map(WmsGoodsSalesDto::getSpecId).collect(Collectors.toList());

        OdsGoodSalesApiDto odsGoodSalesApiDto = new OdsGoodSalesApiDto();

        odsGoodSalesApiDto.setSpecIdList(specList);
        //订单时间
        odsGoodSalesApiDto.setBeginTime(goodsSalesDto.getBeginTime());

        odsGoodSalesApiDto.setEndTime(goodsSalesDto.getEndTime());
        //已完成订单 商品出货总数量,总售价,总应收
        List<OdsGoodSalesApiDto> list = omcOrderFeignApi.goodsSales(odsGoodSalesApiDto);


        for (WmsGoodsSalesDto wmsGoodsSalesDto : salesList) {
            //避免比较器报错
            wmsGoodsSalesDto.setNumber(0);
            //计算近三十天成本均价
            wmsGoodsSalesDto.setUnitPrice(((double) wmsGoodsSalesDto.getPriceTotal() / (double) wmsGoodsSalesDto.getNumberTotal()));
            for (OdsGoodSalesApiDto goodSalesApiDto : list) {
                if (wmsGoodsSalesDto.getSpecId().equals(goodSalesApiDto.getSpecId())) {
                    BeanUtils.copyProperties(goodSalesApiDto, wmsGoodsSalesDto);
                }
            }
        }

        Collections.sort(salesList, new Comparator<WmsGoodsSalesDto>() {
            @Override
            public int compare(WmsGoodsSalesDto user1, WmsGoodsSalesDto user2) {
                return (user2.getNumber().compareTo(user1.getNumber()));
            }
        });

        result.setList(salesList);
        return result;
    }

    @Override
    public Integer addOverFlow(WmsPurchaseOrderDto wmsPurchaseOrderDto) {
        //操作wms_stock_in 添加商品
        List<WmsStockIn> list = wmsPurchaseOrderDto.getGoodsList();
        for (WmsStockIn wmsStockIn : list) {
            wmsStockIn.setInType((byte) 3);
            System.out.println(wmsStockIn);
            wmsStockIn.setPurchaseId(wmsPurchaseOrderDto.getPurchaseId());
            wmsStockIn.setWarehouseId(wmsPurchaseOrderDto.getWarehouseId());
            wmsStockIn.setUpdateId(wmsPurchaseOrderDto.getUpdateId());
            //入库时间根据会计要求设为当前时间 而非单据时间
            wmsStockIn.setInboundTime(new Date());
            if (wmsPurchaseOrderDto.getIsDeleted().equals(1)){
                wmsStockIn.setIsDelete(true);
            }else {
                wmsStockIn.setIsDelete(false);
            }

            //查找对应wmsStorage中的
            Example example = new Example(WmsStorage.class);
            example.createCriteria().andEqualTo("specId",wmsStockIn.getSpecId())
                    .andEqualTo("warehouseId",wmsStockIn.getWarehouseId());
            List<WmsStorage> wmsStorages = wmsStorageService.selectByExample(example);
            if (wmsStorages.size()==1) {
                WmsStorage wmsStorage = wmsStorages.get(0);
                //更改库存
                Integer number = wmsStorage.getNumber();
                number+=wmsStockIn.getInNumber();
                wmsStorage.setNumber(number);
                wmsStorage.setUpdateTime(new Date());
                Integer update = wmsStorageService.update(wmsStorage);
            }else {
                return 0;
            }
        }
        System.out.println(list);
        Integer i = wmsStockInMapper.insertList(list);

        if (i > 0) {
            if (list == null || list.size() < 1) {
                return 0;
            }
            return i;
        }

        return i;
    }

    @Override
    public PageInfo<WmsGoodsSalesDto> goodsSalesJoin(Integer page, Integer size, WmsGoodsSalesDto goodsSalesDto) {

        //分类
        if (goodsSalesDto.getParentId() != null || goodsSalesDto.getCategoryId() != null) {
            ProdCategoryDto prodCategoryDto = new ProdCategoryDto();
            prodCategoryDto.setParentId(goodsSalesDto.getParentId());
            prodCategoryDto.setCategoryId(goodsSalesDto.getCategoryId());
            List<Long> leaf = pmcFeignApi.findLeaf(prodCategoryDto);
            goodsSalesDto.setCategoryIdList(leaf);
            goodsSalesDto.setCategoryId(null);
        }
        PageHelper.startPage(page, size);

        //出货的商品数量
        //订单状态已完成
        goodsSalesDto.setOrderType((byte)2);
        //商品出货总数量,总售价,总应收
        goodsSalesDto.setGoodsStatus((byte)0);

        List<WmsGoodsSalesDto> salesList = wmsStockInMapper.goodsSalesJoin(goodsSalesDto);

        if (salesList==null||salesList.size()==0){
            return null;
        }

        PageInfo<WmsGoodsSalesDto> result = new PageInfo<>(salesList);

        //赠品的出货数量
        goodsSalesDto.setGoodsStatus((byte)4);

        List<WmsGoodsSalesDto> giftList = wmsStockInMapper.goodsSalesJoin(goodsSalesDto);

        //统计近三十天成本单价 对应总数量 总金额
        WmsGoodsSalesDto dto = new WmsGoodsSalesDto();

        List<Long> collect = new ArrayList<>();

        List<Long> categoryList = new ArrayList<>();

        for (WmsGoodsSalesDto wmsGoodsSalesDto : salesList) {

            collect.add(wmsGoodsSalesDto.getSpecId());

            categoryList.add(wmsGoodsSalesDto.getCategoryId());
        }

        //List<Long> collect = salesList.stream().map(WmsGoodsSalesDto::getSpecId).collect(Collectors.toList());
        dto.setSpecIdList(collect);

        List<WmsGoodsSalesDto> goodsSales = findGoodsSales(dto);

        List<ProdSpecApiDto> parent = pmcFeignApi.findParent(categoryList);

        for (WmsGoodsSalesDto wmsGoodsSalesDto : salesList) {
            if (giftList!=null&&giftList.size()>0) {
                for (WmsGoodsSalesDto salesDto : giftList) {
                    if (salesDto.getSpecId().equals(wmsGoodsSalesDto.getSpecId())) {
                        //赠品数量
                        wmsGoodsSalesDto.setGiftNumber(salesDto.getNumber());
                    }
                }
            }
            if(goodsSales!=null&&goodsSales.size()>0) {
                for (WmsGoodsSalesDto goodSalesApiDto : goodsSales) {
                    if (wmsGoodsSalesDto.getSpecId().equals(goodSalesApiDto.getSpecId())) {
                        //总数量 总金额
                        wmsGoodsSalesDto.setPriceTotal(goodSalesApiDto.getPriceTotal());
                        wmsGoodsSalesDto.setNumberTotal(goodSalesApiDto.getNumberTotal());
                        wmsGoodsSalesDto.setStockPrice(goodSalesApiDto.getStockPrice());
                        wmsGoodsSalesDto.setMarketPrice(goodSalesApiDto.getMarketPrice());
                        wmsGoodsSalesDto.setSaleType(goodSalesApiDto.getSaleType());
                        wmsGoodsSalesDto.setHasRebate(goodSalesApiDto.getHasRebate());
                        //计算近三十天成本均价
                        wmsGoodsSalesDto.setUnitPrice(((double) wmsGoodsSalesDto.getPriceTotal() / (double) wmsGoodsSalesDto.getNumberTotal()));
                    }
                }
            }

            if(parent!=null&&parent.size()>0) {
                for (ProdSpecApiDto prodSpecApiDto : parent) {
                    if (prodSpecApiDto.getCategoryId().equals(wmsGoodsSalesDto.getCategoryId())) {
                        wmsGoodsSalesDto.setParentId(prodSpecApiDto.getParentId());
                        wmsGoodsSalesDto.setParentName(prodSpecApiDto.getParentName());
                        wmsGoodsSalesDto.setCategoryName(prodSpecApiDto.getCategoryName());
                    }
                }
            }
        }

        return result;
    }

    @Override
    public List<WmsGoodsSalesDto> costUnitPriceBylimit(List<Long> ids) {
        List<WmsGoodsSalesDto> result = new ArrayList<>();
        for (Long id : ids) {
            WmsGoodsSalesDto dto = wmsStockInMapper.costUnitPriceBylimit(id);
            result.add(dto);
        }
        return result;
    }

    @Override
    public PageInfo<WmsStockInDto> countBySpec(WmsStockInDto wmsStockInDto,Integer page,Integer size) {
        //分类
        if (wmsStockInDto.getParentId() != null || wmsStockInDto.getCategoryId() != null) {
            ProdCategoryDto prodCategoryDto = new ProdCategoryDto();
            prodCategoryDto.setParentId(wmsStockInDto.getParentId());
            prodCategoryDto.setCategoryId(wmsStockInDto.getCategoryId());
            List<Long> leaf = pmcFeignApi.findLeaf(prodCategoryDto);
            wmsStockInDto.setCategoryIdList(leaf);
            wmsStockInDto.setCategoryId(null);
        }
        PageHelper.startPage(page, size);

        List<WmsStockInDto> list = wmsStockInMapper.countBySpec(wmsStockInDto);

        if (list==null||list.size()==0){
            return null;
        }

        PageInfo<WmsStockInDto> result = new PageInfo<>(list);

        List<Long> collect = list.stream().map(WmsStockInDto::getCategoryId).collect(Collectors.toList());

        List<ProdSpecApiDto> parent = pmcFeignApi.findParent(collect);

        if (parent!=null&&parent.size()>0){
            for (WmsStockInDto stockInDto : list) {
                for (ProdSpecApiDto prodSpecApiDto : parent) {
                    if (stockInDto.getCategoryId().equals(prodSpecApiDto.getCategoryId())){
                        stockInDto.setParentId(prodSpecApiDto.getParentId());
                        stockInDto.setParentName(prodSpecApiDto.getParentName());
                        stockInDto.setCategoryName(prodSpecApiDto.getCategoryName());
                    }
                 }
            }
        }

        result.setList(list);
        return result;
    }

    @Override
    public List<WmsStockInDto> findDescPurchasePrice(List<Long> specIds) {
        List<WmsStockInDto> list = wmsStockInMapper.findDescPurchasePrice(specIds);
        return list;
    }

    @Override
    public Integer changeCheckIn(WmsStockInDto wmsStockInDto) {

        wmsStockInDto.setUpdateTime(new Date());
        Integer result = wmsStockInMapper.changeCheckIn(wmsStockInDto);
        return result;
    }


}

